#ifndef _ARCH_IRQ_H
#define _ARCH_IRQ_H

#if __CPU_ARCH__ >= 6

static inline unsigned int arch_local_irq_save(void)
{
    unsigned int flags;
    
    asm volatile(
        "   mrs %0, cpsr    @ arch_local_irq_save\n"
        "   cpsid   i"
        : "=r" (flags) : : "memory", "cc");
    return flags;
}

static inline void arch_local_irq_enable(void)
{   
    asm volatile(
        "   cpsie i         @ arch_local_irq_enable"
        :
        :
        : "memory", "cc");
}

static inline void arch_local_irq_disable(void)
{
    asm volatile(
        "   cpsid i         @ arch_local_irq_disable"
        :
        :
        : "memory", "cc");
}

#else

static inline unsigned int arch_local_irq_save(void)
{
    unsigned int flags, temp;

    asm volatile(
        "   mrs %0, cpsr    @ arch_local_irq_save\n"
        "   orr %1, %0, #128\n"
        "   msr cpsr_c, %1"
        : "=r" (flags), "=r" (temp)
        :
        : "memory", "cc");
    return flags;
}

static inline void arch_local_irq_enable(void)
{
    unsigned int temp;
    asm volatile(
        "   mrs %0, cpsr    @ arch_local_irq_enable\n"
        "   bic %0, %0, #128\n"
        "   msr cpsr_c, %0"
        : "=r" (temp)
        :
        : "memory", "cc");
}

static inline void arch_local_irq_disable(void)
{
    unsigned int temp;
    asm volatile(
        "   mrs %0, cpsr    @ arch_local_irq_disable\n"
        "   orr %0, %0, #128\n"
        "   msr cpsr_c, %0"
        : "=r" (temp)
        :
        : "memory", "cc");
}

#endif

static inline void arch_local_irq_restore(unsigned int flags)
{
    asm volatile(
        "   msr cpsr_c, %0  @ local_irq_restore"
        :
        : "r" (flags)
        : "memory", "cc");
}

#endif /* _ARCH_IRQ_H */

